/* Copyright 2017, 2018, 2019, 2020 Gabriel Czernikier
 *
 * This file is part of Côtehaus.
 * Côtehaus is free software: you can redistribute it and/or modify
 * it under the terms of one of the following:
 * 1. The same dual license as that of Côtehaus itself, of which individual licenses are
 * the MIT License and the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 2. The MIT License.
 * 3. The GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * Côtehaus is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MIT License and the GNU General Public License for more details.
 * You should have received a copy of the MIT License and the GNU General Public License
 * along with Côtehaus.  If not, see <https://opensource.org/licenses/MIT> and <http://www.gnu.org/licenses/>.
 */
#ifndef __CH_SEARCH_ENTRY_H
#define __CH_SEARCH_ENTRY_H

enum search_entry_type_enu {
	PACKAGE,
	REFTYPE,
	STATIC_FIELD,
	STATIC_METHOD
};

// Search entries, in a broad sense. General targets that can be reached by means of a search. Well, not so general, as it only gears reftype and package stuff.
struct search_entry_st {
	union {
		struct {
			lgwseq_t *unqualif_RefTyp;  // The minimal searchable entry for a "REFTYPE" search_entry_type, for instance "Number", "Map", "Entry" and "String"
			struct type_id_st *type_id_target;  // The target of this search
		} reftype;
		struct {
			struct token_list_st *pkg_particles;  // The minimal searchable entry for a "PACKAGE" search_entry_type, for instance "java.lang" is encoded as "lang" -> "java"
			lgwseq_t *pkg_str_cache;  // A cache of a condensed encoding of the package, i.e. "java.lang"
		} pkg;
		struct field_id_st *static_field;
		struct method_id_st *static_method;
	} entry_union;
	struct search_entry_st *parent;  // For instance, the search entries "java.lang" and "Number"  shall be, in a conventional context, the former the parent of the latter
	struct context_st *context;   // the context in which this search_entry_st sprung off
	enum search_entry_type_enu search_entry_type;
	struct list_head search_entry_list;  // List which this search_entry is member of.
};

struct osearch_entry_st {
	struct search_entry_st *origin;
	struct osearch_entry_st *equiv_class_representative, *next_equiv_class;
};

// Adds a struct search_entry_st to global LIST_HEAD(search_entry_head), having as parent the previous struct search_entry_st, and becoming henceforth the parent for a next one added.
struct search_entry_st *add_package_search_entry(struct token_list_st *token_list);
struct search_entry_st *add_reftype_search_entry(struct type_id_st *type_id_target, lgwseq_t *search_entry_string, struct search_entry_st *parent, struct context_st *context);
struct search_entry_st *add_static_field_search_entry(struct field_id_st *static_field_id, struct search_entry_st *parent, struct context_st *context);
struct search_entry_st *add_static_method_search_entry(struct method_id_st *static_method_id, struct context_st *context);
/* conveys these symbolic actions: search_entry_string_concat_interspeding_due_separator(list=reverse(search_entry_produce_parenthood_chain(base)), list_head=name).*/  
lgwseq_t *fullqualif_from_schent(struct search_entry_st *base, lgwseq_t *unqualif);

#endif
